/*
 * @(#) AwardSheetDaoImpl.java
 * Copyright (c) 2011 EdRP, Dayalbagh Educational Institute.
 * All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this  list of conditions and the following disclaimer.
 *
 * Redistribution in binary form must reproducuce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 *
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL ETRG OR ITS CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL,SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Contributors: Members of EdRP, Dayalbagh Educational Institute
 */
package in.ac.dei.edrp.cms.daoimpl.awardsheet;

import in.ac.dei.edrp.cms.common.utility.MyException;
import in.ac.dei.edrp.cms.dao.awardsheet.AwardSheetDao;
import in.ac.dei.edrp.cms.domain.awardsheet.AwardSheetInfoGetter;
import in.ac.dei.edrp.cms.domain.entity.EntityInfoGetter;
import in.ac.dei.edrp.cms.domain.programmaster.ProgramMasterInfoGetter;
import in.ac.dei.edrp.cms.domain.programmaster.ProgramTermDetailsInfoGetter;

import org.apache.log4j.Logger;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import org.springframework.transaction.support.TransactionTemplate;

import java.util.List;
import java.util.StringTokenizer;


/**
 * Implementation class of AwardSheetDao interface
 * @author Manpreet Kaur
 * @date 20-03-2011
 * @version 1.0
 */
public class AwardSheetDaoImpl extends SqlMapClientDaoSupport
    implements AwardSheetDao {
    private static Logger logObj = Logger.getLogger(AwardSheetDaoImpl.class);
    TransactionTemplate transactionTemplate = null;

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    /**
     * Method for getting entity list of given type
     * @param inputObj object containing university id and entity type
     * @return List of entities
     */
    @SuppressWarnings("unchecked")
    public List<ProgramTermDetailsInfoGetter> getEntityList(
        EntityInfoGetter inputObj) {
        List<ProgramTermDetailsInfoGetter> entityList = null;

        try {
            entityList = getSqlMapClientTemplate()
                             .queryForList("AwardSheet.getEntityList", inputObj);
        } catch (Exception e) {
            System.out.println(e);
            logObj.error(e);
        }

        return entityList;
    }

    /**
     * Method for getting program list of given entity
     * @param inputObj object containing  entity id
     * @return List of programs
     */
    @SuppressWarnings("unchecked")
    public List<ProgramTermDetailsInfoGetter> getProgramList(
        EntityInfoGetter inputObj) {
        List<ProgramTermDetailsInfoGetter> progList = getSqlMapClientTemplate()
                                                          .queryForList("AwardSheet.getProgramList",
                inputObj);

        return progList;
    }

    /**
     * Method for getting branch list of given program
     * @param inputObj
     * @return List of branches
     */
    @SuppressWarnings("unchecked")
    public List<ProgramTermDetailsInfoGetter> getBranchList(
        EntityInfoGetter inputObj) {
        List<ProgramTermDetailsInfoGetter> progList = getSqlMapClientTemplate()
                                                          .queryForList("AwardSheet.getBranchList",
                inputObj);

        return progList;
    }

    /**
     * Method for getting specialization list of given program
     * @param inputObj
     * @return List of specializations
     */
    @SuppressWarnings("unchecked")
    public List<ProgramTermDetailsInfoGetter> getSpecializationList(
        ProgramMasterInfoGetter inputObj) {
        List<ProgramTermDetailsInfoGetter> progList = getSqlMapClientTemplate()
                                                          .queryForList("AwardSheet.getSpecializationList",
                inputObj);

        return progList;
    }

    /**
     * Method for getting semester list of given program
     * @param inputObj
     * @return List of semester
     */
    @SuppressWarnings("unchecked")
    public List<ProgramTermDetailsInfoGetter> getSemesterList(
        ProgramMasterInfoGetter inputObj) {
        List<ProgramTermDetailsInfoGetter> progList = getSqlMapClientTemplate()
                                                          .queryForList("AwardSheet.getSemesterList",
                inputObj);

        return progList;
    }

    /**
     * Method for getting course list of given program, branch, specialization, semester
     * @param inputObj
     * @return List of courses
     */
    @SuppressWarnings("unchecked")
    public List<ProgramTermDetailsInfoGetter> getCourseList(
        ProgramMasterInfoGetter inputObj) {
    	List<ProgramTermDetailsInfoGetter> programCourseKeyObject=getProgramCourseKey(inputObj);
    	
    	inputObj.setProgramCourseKey(programCourseKeyObject.get(0).getCode());
    	ProgramTermDetailsInfoGetter datesList = (ProgramTermDetailsInfoGetter) getSqlMapClientTemplate()
        .queryForObject("AwardSheet.getSemesterDates",
inputObj);
inputObj.setStartdate(datesList.getCode());
inputObj.setEndDate(datesList.getName());
    	

        List<ProgramTermDetailsInfoGetter> progList = getSqlMapClientTemplate()
                                                          .queryForList("AwardSheet.getCourseList",
                inputObj);

        return progList;
    }

    /**
     * Method for getting evaluation components
     * @param inputObj
     * @return List
     */
    @SuppressWarnings("unchecked")
    public List<AwardSheetInfoGetter> getEvaluationComponents(
        AwardSheetInfoGetter inputObj) {
        List<AwardSheetInfoGetter> compList = getSqlMapClientTemplate().queryForList("AwardSheet.getEvaluationComponent", inputObj);

        return compList;
    }

    /**
     * Method for getting list of students whose marks are to be entered for given course
     * @param inputObj
     * @return List
     */
    @SuppressWarnings("unchecked")
    public List<AwardSheetInfoGetter> getStudentList(
        ProgramMasterInfoGetter inputObj) {
    	List<AwardSheetInfoGetter> studentList=null;
/*
*   add code to get attempt number also
*/
    	if(inputObj.getDisplayType().equalsIgnoreCase("R")){
    		inputObj.setSystemValue("REM");
    		studentList= getSqlMapClientTemplate().queryForList("AwardSheet.getStudentList",
                    inputObj);
    	}
    	else{
    		studentList= getSqlMapClientTemplate().queryForList("AwardSheet.getStudentList1",
                    inputObj);
    	}
         

        return studentList;
    }

    /**
     * Method for getting marks of students
     * @param inputObj
     * @return List
     */
    @SuppressWarnings("unchecked")
    public List<AwardSheetInfoGetter> getStudentMarks(
        ProgramMasterInfoGetter inputObj) {
    	
    	
        List<AwardSheetInfoGetter> progList = null;

        try {
            if (inputObj.getSystemValue().equalsIgnoreCase("SW")) {
            	List<ProgramTermDetailsInfoGetter> programCourseKeyObject=getProgramCourseKey(inputObj);
            	
            	inputObj.setProgramCourseKey(programCourseKeyObject.get(0).getCode());
                ProgramTermDetailsInfoGetter datesList = (ProgramTermDetailsInfoGetter) getSqlMapClientTemplate()
                                                                                            .queryForObject("AwardSheet.getSemesterDates",
                        inputObj);
                inputObj.setStartdate(datesList.getCode());
                inputObj.setEndDate(datesList.getName());
            }
            progList = getSqlMapClientTemplate()
                           .queryForList("AwardSheet.getStudentMarks", inputObj);
            return progList;
        } catch (Exception e) {
            logger.error("getStudentMarks= " + e);
        }

        return progList;
    }

    /**
     * Method for getting rules for groups
     * @param inputObj
     * @return List
     */
    @SuppressWarnings("unchecked")
    public List<ProgramTermDetailsInfoGetter> getRule(
        ProgramMasterInfoGetter inputObj) {
        try {
            List<ProgramTermDetailsInfoGetter> progList = getSqlMapClientTemplate()
                                                              .queryForList("AwardSheet.getRule",
                    inputObj);

            return progList;
        } catch (Exception e) {
            logger.error("getrule=" + e);
        }

        return null;
    }

    /**
     * Method for checking status of existing entry regarded given course
     * @param inputObj
     * @return String
     */
    public String checkStatus(ProgramMasterInfoGetter inputObj) {
        try {
            ProgramTermDetailsInfoGetter datesList = (ProgramTermDetailsInfoGetter) getSqlMapClientTemplate().queryForObject("AwardSheet.getSemesterDates", inputObj);
            inputObj.setStartdate(datesList.getCode());
            inputObj.setEndDate(datesList.getName());

            ProgramTermDetailsInfoGetter statusList = (ProgramTermDetailsInfoGetter) getSqlMapClientTemplate().queryForObject("AwardSheet.checkStatus", inputObj);
            if(statusList==null){
            	// it means no entry exist in course_marks_approval_status table
            }
            else{
            	return statusList.getName(); // return status for Ex. SUB, APR
            }
        } catch (Exception e) {
            logger.error(e);
        }

        return null;
    }

    /**
     * Method for getting employee code
     * @param inputObj
     * @return List
     */
    @SuppressWarnings("unchecked")
    public List<ProgramTermDetailsInfoGetter> getEmployeeCode(String userId) {
        try {
            List<ProgramTermDetailsInfoGetter> employeeCode = getSqlMapClientTemplate()
                                                                  .queryForList("AwardSheet.getEmployeeCode",
                    userId);

            return employeeCode;
        } catch (Exception e) {
            logger.error("employee code=" + e);
        }

        return null;
    }

    /**
     * Method for getting Program Course Key
     * @param inputObj
     * @return List
     */
    @SuppressWarnings("unchecked")
    public List<ProgramTermDetailsInfoGetter> getProgramCourseKey(
        ProgramMasterInfoGetter inputObj) {
        try {
        	      	
        	
            List<ProgramTermDetailsInfoGetter> programCourseKey = getSqlMapClientTemplate()
                                                                      .queryForList("AwardSheet.getProgramCourseKey",
                    inputObj);
            return programCourseKey;
        } catch (Exception e) {
            logger.error("program course key===" + e);
        }

        return null;
    }

    /**
     * Method for getting List of pending request for given employee
     * @param inputObj
     * @return List
     */
    @SuppressWarnings("unchecked")
    public List<ProgramTermDetailsInfoGetter> getPendingList(
        ProgramMasterInfoGetter inputObj) {
        try {
            List<ProgramTermDetailsInfoGetter> PendingList = getSqlMapClientTemplate().queryForList("AwardSheet.getPendingList", inputObj);

            return PendingList;
        } catch (Exception e) {
            logger.error("pending list " + e);
        }

        return null;
    }

    /**
     * Method for insert/update student marks
     * @param input
     * @return String
     */
    public String saveStudentMarks(AwardSheetInfoGetter input,
        StringTokenizer data) {
        try {
            ProgramTermDetailsInfoGetter datesList = (ProgramTermDetailsInfoGetter) getSqlMapClientTemplate().queryForObject("AwardSheet.getSemesterDates",input);
            input.setStartDate(datesList.getCode());
            input.setEndDate(datesList.getName());

            while (data.hasMoreTokens()) {
                StringTokenizer rowData = new StringTokenizer(data.nextToken(),"|");
                input.setRollNumber(rowData.nextToken());
                input.setEvaluationId(rowData.nextToken());

                String idType = rowData.nextToken();

                if (idType.equalsIgnoreCase("MK")) {
                    input.setMarks(rowData.nextToken());
                    input.setGrades(null);
                    input.setPassfail(null);
                } else if (idType.equalsIgnoreCase("GR")) {
                    input.setGrades(rowData.nextToken());
                    input.setPassfail(null);
                    input.setMarks(null);
                } else if (idType.equalsIgnoreCase("PF")) {
                    input.setPassfail(rowData.nextToken());
                    input.setGrades(null);
                    input.setMarks(null);
                }

                int rowsUpdated = getSqlMapClientTemplate()
                                      .update("AwardSheet.updateStudentMarks",
                        input);

          
                
                
                if (rowsUpdated < 1) {
                    getSqlMapClientTemplate().insert("AwardSheet.insertIntoStudentMarks", input);
                }

                String total = rowData.nextToken();

                if (total.equalsIgnoreCase("undefined")) {
                    total = "0";
                }


                if (input.getDisplayType().equals("I")) {
                    input.setTotalInternal(total);
                    input.setTotalExternal(null);
                } else if (input.getDisplayType().equals("E")) {
                    input.setTotalInternal(null);
                    input.setTotalExternal(total);
                } else if (input.getDisplayType().equals("R")) {
                    input.setTotalInternal(null);
                    input.setTotalExternal(null);
                    input.setTotal(total);
                }

                /*
                 * updating/inserting data into student_marks_summary
                 */
                int rowChanged = getSqlMapClientTemplate().update("AwardSheet.updateStudentMarksSummary",input);

                System.out.println(rowChanged + " row Changed");

                if (rowChanged < 1) {
                    getSqlMapClientTemplate().insert("AwardSheet.insertIntoStudentMarksSummary",input);
                }
            }
        } catch (Exception e) {
            System.out.println(e);
            throw new MyException("E");
        }

        return null;
    }

    /**
     * Method for submitting award sheet for approval
     * @param inputObj
     * @return String
     */
    @SuppressWarnings("unchecked")
    public String submitForApproval(AwardSheetInfoGetter inputObj,
        String function) {
        try {
            inputObj.setUniversityId(inputObj.getEntityId().substring(0, 4));

            ProgramTermDetailsInfoGetter datesList = (ProgramTermDetailsInfoGetter) getSqlMapClientTemplate().queryForObject("AwardSheet.getSemesterDates",inputObj);

            inputObj.setStartDate(datesList.getCode());
            inputObj.setEndDate(datesList.getName());

            List<ProgramTermDetailsInfoGetter> empLevel = getSqlMapClientTemplate().queryForList("AwardSheet.getEmployeeLevel",inputObj);

            if (empLevel.size() > 0) {
                inputObj.setApprovalOrder(empLevel.get(0).getName());
            } else {
                inputObj.setApprovalOrder("0");
            }

            List<ProgramTermDetailsInfoGetter> levelObject = getSqlMapClientTemplate().queryForList("AwardSheet.getNextGetter",inputObj);
            
            System.out.println("before if, request sender:  "+inputObj.getEmployeeCode()+"  size is: "+ levelObject.size());
            
            if (levelObject.size() > 0) {
                inputObj.setApprovalOrder(levelObject.get(0).getName());
                
                inputObj.setRequestGetter(levelObject.get(0).getCode());
                inputObj.setRequestSender(inputObj.getEmployeeCode());
                
                System.out.println("request Sender: "+inputObj.getRequestSender());
            }

            if (function.equalsIgnoreCase("S")) {
                inputObj.setPreviousStatus("WDW");

                int i = getSqlMapClientTemplate().update("AwardSheet.updateStatus", inputObj);

                if (i < 1) {
                    getSqlMapClientTemplate().insert("AwardSheet.insertIntoCourseMarksApprovalStatus", inputObj);
                }
            } else if (function.equalsIgnoreCase("A")) {
                if (levelObject.size() > 0) {
                    inputObj.setStatus("SUB");
                    getSqlMapClientTemplate().insert("AwardSheet.insertIntoCourseMarksApprovalStatus",inputObj);
                }
            }
        } catch (Exception e) {
            System.out.println(e);
            throw new MyException("E");
        }

        return null;
    }

    /**
     * Method for withdrawing award blank sheet previously submitted
     * @param inputObj
     * @return
     */
    public String withdrawRequest(AwardSheetInfoGetter inputObj) {
        int rowsUpdated = 0;

        try {
            ProgramTermDetailsInfoGetter datesList = (ProgramTermDetailsInfoGetter) getSqlMapClientTemplate().queryForObject("AwardSheet.getSemesterDates",inputObj);
            inputObj.setStartDate(datesList.getCode());
            inputObj.setEndDate(datesList.getName());

            rowsUpdated = getSqlMapClientTemplate().update("AwardSheet.withdrawSheet", inputObj);
        } catch (Exception e) {
            throw new MyException("E");
        }

        return rowsUpdated + "";
    }

    /**
     * Method for approving award blank sheet
     * @param inputObj
     * @return
     */
    @SuppressWarnings("unchecked")
    public String approveRequest(AwardSheetInfoGetter inputObj) {
        try {
            List<ProgramTermDetailsInfoGetter> levelObject = getSqlMapClientTemplate().queryForList("AwardSheet.getEmployeeLevel", inputObj);

            if (levelObject.size() > 0) {
                if (levelObject.get(0).getName().equalsIgnoreCase(null)) {
                    throw new Exception("E");
                } else {
                    inputObj.setApprovalOrder(levelObject.get(0).getName());
                }
            } else {
                throw new Exception("E");
            }
            
            System.out.println("Before update query");
            getSqlMapClientTemplate().update("AwardSheet.updateStatus", inputObj);
            
            System.out.println("after update query");
            
            submitForApproval(inputObj, "A");
        } catch (Exception e) {
            throw new MyException("E");
        }

        return "success"; //updated by ankit
    }

    /**
     * Method for rejecting award blank sheet
     * @param inputObj
     * @return
     */
    @SuppressWarnings("unchecked")
    public String rejectRequest(AwardSheetInfoGetter inputObj) {
        try {
            List<ProgramTermDetailsInfoGetter> levelObject = getSqlMapClientTemplate()
                                                                 .queryForList("AwardSheet.getEmployeeLevel",
                    inputObj);

            if (levelObject.size() > 0) {
                if (levelObject.get(0).getName().equalsIgnoreCase(null)) {
                    throw new Exception("");
                } else {
                    inputObj.setApprovalOrder(levelObject.get(0).getName());
                }
            } else {
                throw new Exception("");
            }

            int approvalOrder = Integer.parseInt(inputObj.getApprovalOrder());

            for (int i = approvalOrder; i > 0; i--) {
                if (Integer.parseInt(inputObj.getApprovalOrder()) == approvalOrder) {
                    inputObj.setPreviousStatus("SUB");
                } else {
                    inputObj.setPreviousStatus("APR");
                }

                getSqlMapClientTemplate()
                    .update("AwardSheet.updateStatus", inputObj);
                inputObj.setApprovalOrder(Integer.parseInt(
                        inputObj.getApprovalOrder()) - 1 + "");
            }
        } catch (Exception e) {
            throw new MyException("E");
        }

        return null;
    }
}
